// SDL_01 [SDL-OpenGL Triangle].nova // Using namespace declarations. using Library.OpenGL; using Library.SDL; // The application class. class SdlOpenGLTriangleApp { // Application's data members. private static int SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH; private static uint videoFlags; // Video flags for the "createWindow" function. // Application class's "main" function. public static void main( String[] args ) { // Initialize the class's static data members. SCREEN_WIDTH = 640; // We want our screen width 640 pixels. SCREEN_HEIGHT = 480; // We want our screen height 480 pixels. SCREEN_DEPTH = 32; // We want 32 bits per pixel. // Initialize SDL. if ( SDL.SDL_Init( SDL.SDL_INIT_VIDEO ) < 0 ) { // Report an error if it fails. Stream.writeLine( "Failed initializing SDL Video: " + SDL.SDL_GetError( ) ); // Return instead of SDL_Quit because SDL isn't yet initialized. return; } // Setup the OpenGL pixel format with SDL. if ( setupPixelFormat( ) == false ) { SDL.SDL_Quit( ); // Shutdown SDL. return; // Exit the application. } // Create the window, video flags are also required. if ( createWindow( "SDL_01 [SDL-OpenGL Triangle]", SCREEN_WIDTH, SCREEN_HEIGHT, videoFlags ) == false ) { SDL.SDL_Quit( ); // Shutdown SDL. return; // Exit the application. } // Initialize the OpenGL drawing surface using the resize viewport function. resizeViewport( SCREEN_WIDTH, SCREEN_HEIGHT ); // Run the main rendering and event handling loop. mainLoop( ); // Shutdown SDL. SDL.SDL_Quit( ); } // Sets the pixel format for openGL and video flags for SDL. private static bool setupPixelFormat( ) { // We set the common flags here. videoFlags = SDL.SDL_OPENGL; // It's an openGL window. videoFlags |= SDL.SDL_HWPALETTE; // Exclusive access to hardware colour palette. videoFlags |= SDL.SDL_RESIZABLE; // The window must be resizeable. // Query SDL for information about our video hardware. SDL_VideoInfo videoInfo = SDL.SDL_GetVideoInfo( ); // Check for a "null" return object. if ( videoInfo == null ) { return false; } // Set the system dependant flags. // Is it a hardware surface? if( videoInfo.hw_available == 1 ) { videoFlags |= SDL.SDL_HWSURFACE; } else { videoFlags |= SDL.SDL_SWSURFACE; } // Is hardware blitting available? if ( videoInfo.blit_hw == 1 ) { videoFlags |= SDL.SDL_HWACCEL; } // Tell SDL that the OpenGL rendering is going to be double buffered. SDL.SDL_GL_SetAttribute( SDL.SDL_GL_DOUBLEBUFFER, 1 ); // Specify the size of depth buffer. SDL.SDL_GL_SetAttribute( SDL.SDL_GL_DEPTH_SIZE, SCREEN_DEPTH ); // We aren't going to use the stencil buffer. SDL.SDL_GL_SetAttribute( SDL.SDL_GL_STENCIL_SIZE, 0 ); // The next four lines set the bits allocated per pixel - // - for the accumulation buffer to zero. SDL.SDL_GL_SetAttribute( SDL.SDL_GL_ACCUM_RED_SIZE, 0 ); SDL.SDL_GL_SetAttribute( SDL.SDL_GL_ACCUM_GREEN_SIZE, 0 ); SDL.SDL_GL_SetAttribute( SDL.SDL_GL_ACCUM_BLUE_SIZE, 0 ); SDL.SDL_GL_SetAttribute( SDL.SDL_GL_ACCUM_ALPHA_SIZE, 0 ); return true; } // Create the OpenGL window. private static bool createWindow( String windowName, int width, int height, uint videoFlags ) { // SCREEN_DEPTH is a constant for bits per pixel. if ( SDL.SDL_SetVideoMode( width, height, SCREEN_DEPTH, videoFlags ) == null ) { return false; // Report an error. } // Set the window caption (1st arg) and the icon caption (2nd arg). SDL.SDL_WM_SetCaption( windowName, windowName ); return true; } // This function resizes the viewport for OpenGL. private static void resizeViewport( int width, int height ) { // Prevent a divide by zero error. if ( height == 0 ) { // Make the height equal to one if zero. height = 1; } // Resize the viewport to the whole window. OpenGL.glViewport( 0, 0, width, height ); OpenGL.glMatrixMode( OpenGL.GL_PROJECTION ); // Select the projection matrix. OpenGL.glLoadIdentity( ); // Reset the projection matrix. // Set up the perspective projection matrix. OpenGL.gluPerspective( 45.0, (double)width / (double)height, 1.0, 150.0 ); OpenGL.glMatrixMode( OpenGL.GL_MODELVIEW ); // Select the modelview matrix. } // This function renders the entire scene. private static void renderFrame( ) { // Clear the screen and the depth buffer. OpenGL.glClear( OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT ); // Reset the view. OpenGL.glLoadIdentity( ); // Set the camera's position. OpenGL.gluLookAt( 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); // Render a triangle. OpenGL.glBegin( OpenGL.GL_TRIANGLES ); OpenGL.glColor3f( 0.0f, 0.0f, 1.0f ); // Colour blue. OpenGL.glVertex3f( 0.0f, 1.0f, 0.0f ); // Top vertex. OpenGL.glColor3f( 1.0f, 0.0f, 0.0f ); // Colour red. OpenGL.glVertex3f( -1.0f, -1.0f, 0.0f ); // Left vertex. OpenGL.glColor3f( 0.0f, 1.0f, 0.0f ); // Colour green. OpenGL.glVertex3f( 1.0f, -1.0f, 0.0f ); // Right vertex. OpenGL.glEnd( ); // Swap the buffers. SDL.SDL_GL_SwapBuffers( ); } private static void mainLoop( ) { // Local declarations. bool eventLoopActive = true; SDL_Event event = new SDL_Event( ); // Event handling loop. while ( eventLoopActive ) { // Look for events (like keystrokes, resizing etc.). while( SDL.SDL_PollEvent( event ) == 1 ) { // If user wishes to quit. if ( event.typeID == SDL.SDL_QUIT ) { // This implies our job is done. eventLoopActive = false; } // If there is a resize event. if ( event.typeID == SDL.SDL_VIDEORESIZE ) { // Request SDL to resize the window to the size - // - and depth etc. that we specify. if ( SDL.SDL_SetVideoMode( event.resize.w, event.resize.h, SCREEN_DEPTH, videoFlags ) == null ) { // Exit if there is an error. return; } // Resize the OpenGL viewport. resizeViewport( event.resize.w, event.resize.h ); } } // Render a frame of the OpenGL scene. renderFrame( ); } } }